package com.tanhua.dubbo.server.api;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.dubbo.config.annotation.Service;
import com.mongodb.client.result.DeleteResult;
import com.tanhua.dubbo.server.pojo.*;
import com.tanhua.dubbo.server.service.IdService;
import com.tanhua.dubbo.server.vo.PageInfo;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 圈子发布实现类
 */
@Service(version = "1.0.0")
//@Transactional   //开启事务，老师代码里面未写，确认下会不会报错  todo:事务管理  //会报错  单机mongodb不支持事务
public class QuanZiApiImpl implements QuanZiApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IdService idService;

    /**
     * 发布动态
     * @param publish  传入的发布对象
     * @return
     */
    @Override
    public String savePublish(Publish publish) {
        // 发布到publish中

        //1.校验
        if(null == publish.getUserId()){
            return null;
        }
        try {
            //发布日期
            publish.setCreated(System.currentTimeMillis());
            // 创建发布的主键id，不能传入的就是_id
            publish.setId(ObjectId.get());

            // 创建发布动态的pid   出入的类型为动态/动态id
            publish.setPid(this.idService.createId("publish", publish.getId().toHexString()));
            // 假的权限功能，这里默认给1，公开的
            publish.setSeeType(1);
            this.mongoTemplate.save(publish);//保存到mongodb中

            //发布到个人相册中
            Album album = new Album();
            // 创建时间
            album.setCreated(System.currentTimeMillis());
            album.setId(ObjectId.get());
            album.setPublishId(publish.getId());
            // 保存到mongodb中，这里由于每个用户一个相册，所以每个用户一个表格
            this.mongoTemplate.save(album,"quanzi_album_"+publish.getUserId());

            // 写入好友时间线中，获取好友列表
            Query query = Query.query(Criteria.where("userId").is(publish.getUserId()));
            List<Users> users = this.mongoTemplate.find(query, Users.class);
            for (Users user : users) {
                // 创建时间线对象
                TimeLine timeLine = new TimeLine();
                timeLine.setDate(System.currentTimeMillis());
                timeLine.setId(ObjectId.get());
                timeLine.setPublishId(publish.getId());
                timeLine.setUserId(user.getUserId());
                // 每个好友时间线都是唯一的  写到好友的时间线中
                this.mongoTemplate.save(timeLine,"quanzi_time_line_"+user.getFriendId());
            }
            return publish.getId().toHexString();
        } catch (Exception e) {
            e.printStackTrace();
            // 出错了事务回滚
        }
        return null;
    }

    /**
     *  查询动态
     * @param userId  登录用户id
     * @param page   当前页数
     * @param pageSize   每页显示条数
     * @return
     */
    @Override
    public PageInfo<Publish> queryPublishList(Long userId, Integer page, Integer pageSize) {
        PageRequest pageRequest = PageRequest.of(page - 1, pageSize, Sort.by(Sort.Order.desc("date")));
        Query query = new Query().with(pageRequest);

        // 增加圈子推荐功能
        String collectionName = "quanzi_time_line_" + userId;
        if(null == userId){
            collectionName = "quanzi_time_line_recommend";
        }
        //查询当前用户的时间线表，好友或者推荐过来的数据
        List<TimeLine> timeLineList = this.mongoTemplate.find(query, TimeLine.class, collectionName);

        // 拿到发布信息的publish集合id
        List<ObjectId> publishIds = new ArrayList<>();
        for (TimeLine timeLine : timeLineList) {
            publishIds.add(timeLine.getPublishId());
        }

        //查询发布信息   根据主键查询并且根据创建日期排序；
        Query queryPublish = Query.query(Criteria.where("id").in(publishIds)).with(Sort.by(Sort.Order.desc("created")));
        List<Publish> publishList = this.mongoTemplate.find(queryPublish, Publish.class);
        //创建返回的pageinfo对象
        PageInfo<Publish> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pageSize);
        pageInfo.setRecords(publishList);
        pageInfo.setTotal(0); //不提供总数
        return pageInfo;
    }


    // 点赞
    @Override
    public boolean saveLikeComment(Long userId, String publishId) {
        // 判断是否已经点过赞了，如果点过了九不能再点了
        Query query = Query.query(Criteria
                .where("publishId").is(new ObjectId(publishId))
                .and("userId").is(userId)
                .and("commentType").is(1));
        long count = this.mongoTemplate.count(query, Comment.class);
        if (count > 0) {
            return false;
        }
        // 调用方法保存
        return this.saveComment(userId, publishId, 1, null);
    }

    //取消
    @Override
    public boolean removeComment(Long userId, String publishId, Integer commentType) {
        Query query = Query.query(Criteria
                .where("publishId").is(new ObjectId(publishId))
                .and("userId").is(userId)
                .and("commentType").is(commentType));
        DeleteResult remove = this.mongoTemplate.remove(query, Comment.class);
        return remove.getDeletedCount() > 0;
    }
    //喜欢
    @Override
    public boolean saveLoveComment(Long userId, String publishId) {
        Query query = Query.query(Criteria
                .where("publishId").is(new ObjectId(publishId))
                .and("userId").is(userId)
                .and("commentType").is(3));
        long count = this.mongoTemplate.count(query, Comment.class);
        if (count > 0) {
            return false;
        }
        return this.saveComment(userId, publishId, 3, null);
    }

    /**
     * 保存评论
     * @param userId
     * @param publishId
     * @param type
     * @param content
     * @return
     */
    @Override
    public boolean saveComment(Long userId, String publishId, Integer type, String content) {

        try {
            // 设置评论内容
            Comment comment = new Comment();
            // 评论id
            comment.setId(ObjectId.get());
            //评论用户
            comment.setUserId(userId);
            // 评论文本
            comment.setContent(content);
            // publishId为字符串类型，这里字符串要转一下类型
            comment.setPublishId(new ObjectId(publishId));
            comment.setCommentType(type);
            comment.setCreated(System.currentTimeMillis());

            // 设置发布人的id
            Publish publish = this.mongoTemplate.findById(comment.getPublishId(), Publish.class);
            if (null != publish) {
                comment.setPublishUserId(publish.getUserId());
            } else {
                Video video = this.mongoTemplate.findById(comment.getPublishId(), Video.class);
                if (null != video) {
                    comment.setPublishUserId(video.getUserId());
                }
            }

            this.mongoTemplate.save(comment);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    // 查询评论数
    @Override
    public Long queryCommentCount(String publishId, Integer type) {
        Query query = Query.query(Criteria.where("publishId").is(new ObjectId(publishId)).and("commentType").is(type));
        return this.mongoTemplate.count(query, Comment.class);
    }

    /**
     * 查询单条信息
     * @param publishId
     * @return
     */
    @Override
    public Publish queryPublishById(String publishId) {
        return this.mongoTemplate.findById(new ObjectId(publishId),Publish.class);
    }

    /**
     * 获取评论列表
     * @param publishId
     * @param page
     * @param pageSize
     * @return
     */
    @Override
    public PageInfo<Comment> queryCommentList(String publishId, Integer page, Integer pageSize) {

        Query query = Query.query(Criteria.where("publishId").is(new ObjectId(publishId))
                .and("commentType").is(2)).with(Sort.by(Sort.Order.asc("created")));
        List<Comment> comments = this.mongoTemplate.find(query, Comment.class);
        PageInfo<Comment> pageInfo = new PageInfo<>();
        pageInfo.setTotal(0);
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pageSize);
        pageInfo.setRecords(comments);
        return pageInfo;
    }


    /**
     * 获取该用户的点赞/喜欢/评论列表
     * @param userId
     * @param type
     * @param page
     * @param pageSize
     * @return
     */
    @Override
    public PageInfo<Comment> queryCommentListByUser(Long userId, Integer type, Integer page, Integer pageSize) {

        // 根据时间到倒序
        PageRequest pageRequest = PageRequest.of(page - 1, pageSize, Sort.by(Sort.Order.desc("created")));
        Query query = new Query(Criteria
                .where("publishUserId").is(userId)
                .and("commentType").is(type)).with(pageRequest);

        List<Comment> commentList = this.mongoTemplate.find(query, Comment.class);

        PageInfo<Comment> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pageSize);
        pageInfo.setRecords(commentList);
        pageInfo.setTotal(0); //不提供总数
        return pageInfo;
    }

    @Override
    public List<Publish> queryPublishByPids(List<Long> pidList) {
        Query query = Query.query(Criteria.where("pid").in(pidList));
        return this.mongoTemplate.find(query,Publish.class);
    }


    /**
     * 查询自己的相册
     * @param userId   今日佳人的id
     * @param page
     * @param pageSize
     * @return
     */
    @Override
    public PageInfo<Publish> queryAlbumList(Long userId, Integer page, Integer pageSize) {
        PageInfo<Publish> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pageSize);
        pageInfo.setTotal(0); //不提供总数

        // 通过创建时间排序
        PageRequest pageRequest = PageRequest.of(page - 1, pageSize, Sort.by(Sort.Order.desc("created")));
        Query query = new Query().with(pageRequest);
        List<Album> albumList = this.mongoTemplate.find(query, Album.class, "quanzi_album_" + userId);

        // 如果查询结果为空，则代表没发过动态，直接返回为空集合
        if(CollectionUtils.isEmpty(albumList)){
            return pageInfo;
        }

        // 遍历集合获取动态id集合
        List<ObjectId> publishIds = new ArrayList<>();
        for (Album album : albumList) {
            publishIds.add(album.getPublishId());
        }

        //查询发布信息
        Query queryPublish = Query.query(Criteria.where("id").in(publishIds)).with(Sort.by(Sort.Order.desc("created")));
        List<Publish> publishList = this.mongoTemplate.find(queryPublish, Publish.class);

        pageInfo.setRecords(publishList);

        return pageInfo;
    }
}
